<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>JS 对象实现继承的几种方法以及优缺点 | 我的世界</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="icon" href="/notes/favicon.ico">
    <link rel="manifest" href="/notes/manifest.json">
    <meta name="description" content="学习，生活，还有美食~">
    
    <link rel="preload" href="/notes/assets/css/0.styles.8453c794.css" as="style"><link rel="preload" href="/notes/assets/js/app.f19b5e39.js" as="script"><link rel="preload" href="/notes/assets/js/2.69392339.js" as="script"><link rel="preload" href="/notes/assets/js/34.5a5b6c6e.js" as="script"><link rel="preload" href="/notes/assets/js/14.e376f3f7.js" as="script"><link rel="prefetch" href="/notes/assets/js/10.4748ef2e.js"><link rel="prefetch" href="/notes/assets/js/11.4ec67c3b.js"><link rel="prefetch" href="/notes/assets/js/12.db234a0a.js"><link rel="prefetch" href="/notes/assets/js/13.0bdeeeea.js"><link rel="prefetch" href="/notes/assets/js/15.873f63d0.js"><link rel="prefetch" href="/notes/assets/js/16.6d650151.js"><link rel="prefetch" href="/notes/assets/js/17.f0bcb5c9.js"><link rel="prefetch" href="/notes/assets/js/18.7dffee3a.js"><link rel="prefetch" href="/notes/assets/js/19.5f0252c4.js"><link rel="prefetch" href="/notes/assets/js/20.abea2681.js"><link rel="prefetch" href="/notes/assets/js/21.252713aa.js"><link rel="prefetch" href="/notes/assets/js/22.c99488d0.js"><link rel="prefetch" href="/notes/assets/js/23.3839292f.js"><link rel="prefetch" href="/notes/assets/js/24.9cc2f325.js"><link rel="prefetch" href="/notes/assets/js/25.e9dcd2f1.js"><link rel="prefetch" href="/notes/assets/js/26.31898ae6.js"><link rel="prefetch" href="/notes/assets/js/27.88db2371.js"><link rel="prefetch" href="/notes/assets/js/28.2d29c56c.js"><link rel="prefetch" href="/notes/assets/js/29.a0b42251.js"><link rel="prefetch" href="/notes/assets/js/3.48b2b659.js"><link rel="prefetch" href="/notes/assets/js/30.9b38a2bb.js"><link rel="prefetch" href="/notes/assets/js/31.d374da8e.js"><link rel="prefetch" href="/notes/assets/js/32.7868c3f3.js"><link rel="prefetch" href="/notes/assets/js/33.87730e15.js"><link rel="prefetch" href="/notes/assets/js/35.1deedbd4.js"><link rel="prefetch" href="/notes/assets/js/36.d39f2b24.js"><link rel="prefetch" href="/notes/assets/js/37.d87637b4.js"><link rel="prefetch" href="/notes/assets/js/38.d118907c.js"><link rel="prefetch" href="/notes/assets/js/39.9f2c8514.js"><link rel="prefetch" href="/notes/assets/js/4.161aee82.js"><link rel="prefetch" href="/notes/assets/js/40.917feb30.js"><link rel="prefetch" href="/notes/assets/js/41.78e1b969.js"><link rel="prefetch" href="/notes/assets/js/42.cd6ac9d4.js"><link rel="prefetch" href="/notes/assets/js/43.961a438d.js"><link rel="prefetch" href="/notes/assets/js/44.ef1661d7.js"><link rel="prefetch" href="/notes/assets/js/45.b89cd059.js"><link rel="prefetch" href="/notes/assets/js/46.8ca9e560.js"><link rel="prefetch" href="/notes/assets/js/47.a35bec74.js"><link rel="prefetch" href="/notes/assets/js/48.953bb15e.js"><link rel="prefetch" href="/notes/assets/js/49.ae614c87.js"><link rel="prefetch" href="/notes/assets/js/5.ef4783db.js"><link rel="prefetch" href="/notes/assets/js/50.a9fbc190.js"><link rel="prefetch" href="/notes/assets/js/51.12ae367b.js"><link rel="prefetch" href="/notes/assets/js/52.57a5efe4.js"><link rel="prefetch" href="/notes/assets/js/53.861eb65b.js"><link rel="prefetch" href="/notes/assets/js/54.3bc1c9a1.js"><link rel="prefetch" href="/notes/assets/js/55.f724b26c.js"><link rel="prefetch" href="/notes/assets/js/56.02e48e7a.js"><link rel="prefetch" href="/notes/assets/js/6.72ed1ea6.js"><link rel="prefetch" href="/notes/assets/js/7.f1e39dec.js"><link rel="prefetch" href="/notes/assets/js/8.84b75613.js"><link rel="prefetch" href="/notes/assets/js/9.e1cd5390.js">
    <link rel="stylesheet" href="/notes/assets/css/0.styles.8453c794.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/notes/" class="home-link router-link-active"><img src="/notes/images/fish.gif" alt="我的世界" class="logo"> <span class="site-name can-hide">我的世界</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/notes/notes/" class="nav-link router-link-active">🎓 学习</a></div><div class="nav-item"><a href="/notes/life/" class="nav-link">🏸 生活</a></div> <a href="https://gitee.com/zgj6" target="_blank" rel="noopener noreferrer" class="repo-link">
    git
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/notes/notes/" class="nav-link router-link-active">🎓 学习</a></div><div class="nav-item"><a href="/notes/life/" class="nav-link">🏸 生活</a></div> <a href="https://gitee.com/zgj6" target="_blank" rel="noopener noreferrer" class="repo-link">
    git
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p title="学习笔记" class="sidebar-heading open"><span>学习笔记</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/notes/notes/" aria-current="page" title="目录 · 分类" class="sidebar-link">目录 · 分类</a></li><li><a href="/notes/notes/css_note.html" title="CSS 基础用法收集" class="sidebar-link">CSS 基础用法收集</a></li><li><a href="/notes/notes/fe-effects-collection.html" title="前端实用特效 · Demo" class="sidebar-link">前端实用特效 · Demo</a></li><li><a href="/notes/notes/git-notes.html" title="git 笔记" class="sidebar-link">git 笔记</a></li><li><a href="/notes/notes/js-notes.html" title="JavaScript 笔记" class="sidebar-link">JavaScript 笔记</a></li><li><a href="/notes/notes/nodejs-notes.html" title="Node.js学习" class="sidebar-link">Node.js学习</a></li><li><a href="/notes/notes/ports.html" title="端口占用查询" class="sidebar-link">端口占用查询</a></li><li><a href="/notes/notes/vuepress.html" title="vuepress使用中遇到的问题" class="sidebar-link">vuepress使用中遇到的问题</a></li><li><a href="/notes/notes/windows.html" title="Windows" class="sidebar-link">Windows</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p title="JavaScript 高程笔记" class="sidebar-heading"><span>JavaScript 高程笔记</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="HTTP" class="sidebar-heading"><span>HTTP</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="微信小程序" class="sidebar-heading"><span>微信小程序</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="TS" class="sidebar-heading"><span>TS</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="Vite" class="sidebar-heading"><span>Vite</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="interviewquestion" class="sidebar-heading"><span>interviewquestion</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="AI" class="sidebar-heading"><span>AI</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="UE" class="sidebar-heading"><span>UE</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="js-对象实现继承的几种方法以及优缺点"><a href="#js-对象实现继承的几种方法以及优缺点" class="header-anchor">#</a> JS 对象实现继承的几种方法以及优缺点</h1> <blockquote><p><a href="https://juejin.im/post/5ccff45a51882541b07a9e3d" target="_blank" rel="noopener noreferrer">js实现继承的方法以及优缺点<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p></blockquote> <h2 id="原型链继承"><a href="#原型链继承" class="header-anchor">#</a> 原型链继承</h2> <p>使用原型链的原理实现继承</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">SuperType</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'SuperType'</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>colors <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'red'</span><span class="token punctuation">,</span> <span class="token string">'green'</span><span class="token punctuation">,</span> <span class="token string">'blue'</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token class-name">SuperType</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayName</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">SubType</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>subName <span class="token operator">=</span> <span class="token string">'SubType'</span>
<span class="token punctuation">}</span>
<span class="token class-name">SubType</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SuperType</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token class-name">SubType</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">saySubName</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>subName<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> sub <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SubType</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
sub<span class="token punctuation">.</span><span class="token function">saySubName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// SubType</span>
sub<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// SuperType</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sub <span class="token keyword">instanceof</span> <span class="token class-name">SubType</span><span class="token punctuation">)</span> <span class="token comment">// true</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sub <span class="token keyword">instanceof</span> <span class="token class-name">SuperType</span><span class="token punctuation">)</span> <span class="token comment">// true</span>

sub<span class="token punctuation">.</span>colors<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">'yellow'</span><span class="token punctuation">)</span>
<span class="token keyword">var</span> sub2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SubType</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sub<span class="token punctuation">.</span>colors<span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sub2<span class="token punctuation">.</span>colors<span class="token punctuation">)</span> <span class="token comment">// 原型链上的数组也被修改了</span>
</code></pre></div><ul><li>【优点】
<ul><li>可以使用 <code>instanceof</code> 操作符判断实例是否属于被继承的对象</li></ul></li> <li>【缺点】
<ul><li>如果修改了实例原型链上父类的引用类型值，会影响其他实例</li> <li>不能向超类型的构造函数传参</li></ul></li></ul> <h2 id="借用构造函数继承"><a href="#借用构造函数继承" class="header-anchor">#</a> 借用构造函数继承</h2> <p>在子类型构造函数的内部调用超类型的构造函数</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">SuperType</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name
  <span class="token keyword">this</span><span class="token punctuation">.</span>colors <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'red'</span><span class="token punctuation">,</span> <span class="token string">'green'</span><span class="token punctuation">,</span> <span class="token string">'blue'</span><span class="token punctuation">]</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">sayName</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token class-name">SuperType</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>test <span class="token operator">=</span> <span class="token string">&quot;TEST&quot;</span>
<span class="token class-name">SuperType</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hello world'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">SubType</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">SuperType</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token string">&quot;Nico&quot;</span><span class="token punctuation">)</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token number">23</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> sub <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SubType</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sub<span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sub<span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token comment">// Nico</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sub<span class="token punctuation">.</span>age<span class="token punctuation">)</span> <span class="token comment">// 23</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sub <span class="token keyword">instanceof</span> <span class="token class-name">SuperType</span><span class="token punctuation">)</span> <span class="token comment">// false</span>
</code></pre></div><ul><li>【优点】
<ul><li>可以在子类型构造函数中向超类型构造函数传参</li> <li>由于是在子类型构造函数创建时调用超类型的构造函数，所以生成每个实例的属性不会互相干扰</li></ul></li> <li>【缺点】
<ul><li>不能使用 <code>instanceof</code> 操作符判断实例是否属于被继承的对象</li> <li>无法复用超类型的函数（会被重复复制），在超类型原型中定义的属性，子类型无法访问</li></ul></li></ul> <h2 id="组合继承"><a href="#组合继承" class="header-anchor">#</a> 组合继承</h2> <p>这是<strong>JavaScript最常用的继承模式</strong>，将<code>原型链继承</code>和<code>借用构造函数继承</code>的技术组合到一块，从而取长补短的一种继承模式</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">SuperType</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name
  <span class="token keyword">this</span><span class="token punctuation">.</span>colors <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'red'</span><span class="token punctuation">,</span> <span class="token string">'green'</span><span class="token punctuation">,</span> <span class="token string">'blue'</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token class-name">SuperType</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayName</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">SubType</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 继承实例属性</span>
  <span class="token function">SuperType</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age
<span class="token punctuation">}</span>
<span class="token comment">// 继承公共属性</span>
<span class="token class-name">SubType</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SuperType</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token class-name">SubType</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayAge</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>age<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> sub <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SubType</span><span class="token punctuation">(</span><span class="token string">'Nico'</span><span class="token punctuation">,</span> <span class="token number">18</span><span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sub<span class="token punctuation">)</span>
sub<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// Nico</span>
sub<span class="token punctuation">.</span><span class="token function">sayAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 18</span>
</code></pre></div><ul><li>【优点】
<ul><li><code>原型链继承</code>和<code>借用构造函数继承</code>的优点</li></ul></li> <li>【缺点】
<ul><li>无论什么情况，都会调用2次超类型构造函数：一次是在创建子类型原型的时候，另一次是在子类型构造函数内部</li></ul></li></ul> <h2 id="原型式继承"><a href="#原型式继承" class="header-anchor">#</a> 原型式继承</h2> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">object</span><span class="token punctuation">(</span><span class="token parameter">o</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">function</span> <span class="token constant">F</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token class-name">F</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> o
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">F</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> person <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">&quot;Nicholas&quot;</span><span class="token punctuation">,</span>
    friends<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">&quot;Shelby&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;Court&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;Van&quot;</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> anotherPerson <span class="token operator">=</span> <span class="token function">object</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span>
anotherPerson<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">&quot;Greg&quot;</span>
anotherPerson<span class="token punctuation">.</span>friends<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">&quot;Rob&quot;</span><span class="token punctuation">)</span>

<span class="token keyword">var</span> yetAnotherPerson <span class="token operator">=</span> <span class="token function">object</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span>
yetAnotherPerson<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">&quot;Linda&quot;</span>
yetAnotherPerson<span class="token punctuation">.</span>friends<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">&quot;Barbie&quot;</span><span class="token punctuation">)</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>anotherPerson<span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>friends<span class="token punctuation">)</span>
</code></pre></div><p>ES5 通过新增 <code>Object.create()</code> 规范了原型式继承，这个方法接收2个参数，一个用作新对象的原型的对象和一个为新对象新增额外属性的对象（可选的）。
在传入一个参数的情况下，<code>Object.create()</code> 的行为与上述 <code>object()</code> 方法相同。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> person <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">&quot;Nicholas&quot;</span><span class="token punctuation">,</span>
    friends<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">&quot;Shelby&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;Court&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;Van&quot;</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> anotherPerson <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>person<span class="token punctuation">,</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token punctuation">{</span>
        value<span class="token operator">:</span> <span class="token string">&quot;Greg&quot;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
anotherPerson<span class="token punctuation">.</span>friends<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">&quot;Rob&quot;</span><span class="token punctuation">)</span>

<span class="token keyword">var</span> yetAnotherPerson <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>person<span class="token punctuation">,</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token punctuation">{</span>
        value<span class="token operator">:</span> <span class="token string">&quot;Linda&quot;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
yetAnotherPerson<span class="token punctuation">.</span>friends<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">&quot;Barbie&quot;</span><span class="token punctuation">)</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>anotherPerson<span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>friends<span class="token punctuation">)</span>
</code></pre></div><blockquote><p>不必新建构造函数，继承简单；但引用类型的值是共享的，容易被篡改</p></blockquote> <h2 id="寄生式继承"><a href="#寄生式继承" class="header-anchor">#</a> 寄生式继承</h2> <p>创建一个仅用于封装过程的函数，该函数在内部用<code>原型式继承</code>创建一个新对象，并用某种方式增强新对象</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">createAnother</span><span class="token punctuation">(</span><span class="token parameter">original</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> clone <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>original<span class="token punctuation">)</span>
    clone<span class="token punctuation">.</span><span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hi'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> clone
<span class="token punctuation">}</span>

<span class="token keyword">var</span> person <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">&quot;Nicholas&quot;</span><span class="token punctuation">,</span>
    friends<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">&quot;Shelby&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;Court&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;Van&quot;</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> anotherPerson <span class="token operator">=</span> <span class="token function">createAnother</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span>
anotherPerson<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>anotherPerson<span class="token punctuation">)</span>
</code></pre></div><blockquote><p>由于不能做到函数复用而降低效率，与<code>构造函数</code>模式类似</p></blockquote> <h2 id="寄生组合式继承"><a href="#寄生组合式继承" class="header-anchor">#</a> 寄生组合式继承</h2> <p>组合继承是JS最常用的继承模式，但它有一个缺点就是会调用2遍构造函数，寄生组合式继承解决了这个问题</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">inheritPrototype</span><span class="token punctuation">(</span><span class="token parameter">SubType<span class="token punctuation">,</span> SuperType</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> prototype <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token class-name">SuperType</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span>  <span class="token comment">// 创建对象</span>
    prototype<span class="token punctuation">.</span>constructor <span class="token operator">=</span> SubType <span class="token comment">// 增强对象</span>
    <span class="token class-name">SubType</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> prototype <span class="token comment">// 指定对象</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">SuperType</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name
    <span class="token keyword">this</span><span class="token punctuation">.</span>colors <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">&quot;red&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;blue&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;green&quot;</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token class-name">SuperType</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayName</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">SubType</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">SuperType</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age
<span class="token punctuation">}</span>
<span class="token function">inheritPrototype</span><span class="token punctuation">(</span>SubType<span class="token punctuation">,</span> SuperType<span class="token punctuation">)</span>

<span class="token keyword">var</span> sub <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SubType</span><span class="token punctuation">(</span><span class="token string">'Nico'</span><span class="token punctuation">,</span> <span class="token number">18</span><span class="token punctuation">)</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sub<span class="token punctuation">)</span>
sub<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><blockquote><p>寄生组合式继承的高效率体现在它只调用了一次 <code>SuperType</code> 的构造函数，并且因此避免了在 <code>SubType.prototype</code> 上创建多余的属性；原型链可以保持不变，可以使用 <code>instanceof</code> 和 <code>isPrototypeOf()</code>。普遍认为寄生组合式继承是应用类型最理想的继承范式</p></blockquote> <h2 id="class继承"><a href="#class继承" class="header-anchor">#</a> Class继承</h2> <p>堪称完美，但需要浏览器支持ES6语法，或使用Babel进行polyfill</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">class</span> <span class="token class-name">Cat</span> <span class="token keyword">extends</span> <span class="token class-name">Animals</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre></div></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">2023-4-5 17:45:19</span></div></footer> <!----> </main></div><div class="global-ui"><!----><div id="live2d-widget" class="live2d-widget-container" style="position:fixed;right:65px;bottom:0px;width:135px;height:300px;z-index:99999;opacity:0.8;pointer-events:none;"><canvas id="live2d_canvas" width="135" height="300" class="live2d_canvas" style="position:absolute;left:0px;top:0px;width:135px;height:300px;"></canvas></div></div></div>
    <script src="/notes/assets/js/app.f19b5e39.js" defer></script><script src="/notes/assets/js/2.69392339.js" defer></script><script src="/notes/assets/js/34.5a5b6c6e.js" defer></script><script src="/notes/assets/js/14.e376f3f7.js" defer></script>
  </body>
</html>
